package com.bugsnag.ohos;

import ohos.app.Context;

import java.io.File;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * ConfigInternal
 *
 * @since 2021-07-02
 */
public class ConfigInternal implements CallbackAware, MetadataAware, UserAware {
    private static final int DEFAULT_MAX_BREADCRUMBS = 25;
    private static final int DEFAULT_MAX_PERSISTED_SESSIONS = 128;
    private static final int DEFAULT_MAX_PERSISTED_EVENTS = 32;
    private static final long DEFAULT_LAUNCH_CRASH_THRESHOLD_MS = 5000L;
    protected Set<Plugin> plugins = new HashSet<Plugin>();
    String apiKey;
    CallbackState callbackState = new CallbackState();
    String appVersion = null;
    int versionCode = 0;
    String releaseStage = null;
    ThreadSendPolicy sendThreads = ThreadSendPolicy.ALWAYS;
    boolean persistUser = false;
    long launchDurationMillis = DEFAULT_LAUNCH_CRASH_THRESHOLD_MS;
    boolean sendLaunchCrashesSynchronously = true;
    ErrorTypes enabledErrorTypes = new ErrorTypes();
    boolean autoDetectErrors = true;
    String appType = "ohos";
    Logger logger = new DebugLogger();
    Delivery delivery = null;
    EndpointConfiguration endpoints = new EndpointConfiguration();
    int maxBreadcrumbs = DEFAULT_MAX_BREADCRUMBS;
    int maxPersistedEvents = DEFAULT_MAX_PERSISTED_EVENTS;
    int maxPersistedSessions = DEFAULT_MAX_PERSISTED_SESSIONS;
    String context = null;
    boolean autoTrackSessions = true;
    Set<String> discardClasses = new HashSet<>();
    Set<String> enabledReleaseStages = null;
    Set<BreadcrumbType> enabledBreadcrumbTypes = null;
    Set<String> projectPackages = new HashSet<>();
    File persistenceDirectory = null;
    private User user = new User();
    private MetadataState metadataState = new MetadataState();

    /**
     * constructor
     *
     * @param apiKey
     */
    public ConfigInternal(String apiKey) {
        this.apiKey = apiKey;
    }

    public long getLaunchDurationMillis() {
        return launchDurationMillis;
    }

    public void setLaunchDurationMillis(long launchDurationMillis) {
        this.launchDurationMillis = launchDurationMillis;
    }

    public MetadataState getMetadataState() {
        return metadataState;
    }

    public void setMetadataState(MetadataState metadataState) {
        this.metadataState = metadataState;
    }

    public boolean getAutoTrackSessions() {
        return autoTrackSessions;
    }

    public void setAutoTrackSessions(Boolean autoTrackSessions) {
        this.autoTrackSessions = autoTrackSessions;
    }

    public Set<Plugin> getPlugins() {
        return plugins;
    }

    public void setPlugins(Set<Plugin> plugins) {
        this.plugins = plugins;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public void setUser(String id, String email, String name) {
        user = new User(id, email, name);
    }

    public Set<String> getProjectPackages() {
        return projectPackages;
    }

    public void setProjectPackages(Set<String> projectPackages) {
        this.projectPackages = projectPackages;
    }

    public Set<String> getDiscardClasses() {
        return discardClasses;
    }

    public void setDiscardClasses(Set<String> discardClasses) {
        this.discardClasses = discardClasses;
    }

    public Set<String> getEnabledReleaseStages() {
        return enabledReleaseStages;
    }

    public void setEnabledReleaseStages(Set<String> enabledReleaseStages) {
        this.enabledReleaseStages = enabledReleaseStages;
    }

    public Set<BreadcrumbType> getEnabledBreadcrumbTypes() {
        return enabledBreadcrumbTypes;
    }

    public void setEnabledBreadcrumbTypes(Set<BreadcrumbType> enabledBreadcrumbTypes) {
        this.enabledBreadcrumbTypes = enabledBreadcrumbTypes;
    }

    public String getContext() {
        return context;
    }

    public void setContext(String context) {
        this.context = context;
    }

    public int getMaxBreadcrumbs() {
        return maxBreadcrumbs;
    }

    public void setMaxBreadcrumbs(int maxBreadcrumbs) {
        this.maxBreadcrumbs = maxBreadcrumbs;
    }

    public int getMaxPersistedEvents() {
        return maxPersistedEvents;
    }

    public void setMaxPersistedEvents(int maxPersistedEvents) {
        this.maxPersistedEvents = maxPersistedEvents;
    }

    public int getMaxPersistedSessions() {
        return maxPersistedSessions;
    }

    public void setMaxPersistedSessions(int maxPersistedSessions) {
        this.maxPersistedSessions = maxPersistedSessions;
    }

    public EndpointConfiguration getEndpoints() {
        return endpoints;
    }

    public void setEndpoints(EndpointConfiguration endpoints) {
        this.endpoints = endpoints;
    }

    public Delivery getDelivery() {
        return delivery;
    }

    public void setDelivery(Delivery delivery) {
        this.delivery = delivery;
    }

    public Logger getLogger() {
        return logger;
    }

    public void setLogger(Logger logger) {
        this.logger = logger;
    }

    public String getAppType() {
        return appType;
    }

    public void setAppType(String appType) {
        this.appType = appType;
    }

    public boolean getAutoDetectErrors() {
        return autoDetectErrors;
    }

    public void setAutoDetectErrors(Boolean autoDetectErrors) {
        this.autoDetectErrors = autoDetectErrors;
    }

    public ErrorTypes getEnabledErrorTypes() {
        return enabledErrorTypes;
    }

    public void setEnabledErrorTypes(ErrorTypes enabledErrorTypes) {
        this.enabledErrorTypes = enabledErrorTypes;
    }

    public String getApiKey() {
        return apiKey;
    }

    public void setApiKey(String apiKey) {
        this.apiKey = apiKey;
    }

    public String getAppVersion() {
        return appVersion;
    }

    public void setAppVersion(String appVersion) {
        this.appVersion = appVersion;
    }

    public int getVersionCode() {
        return versionCode;
    }

    public void setVersionCode(int versionCode) {
        this.versionCode = versionCode;
    }

    public String getReleaseStage() {
        return releaseStage;
    }

    public void setReleaseStage(String releaseStage) {
        this.releaseStage = releaseStage;
    }

    public ThreadSendPolicy getSendThreads() {
        return sendThreads;
    }

    public void setSendThreads(ThreadSendPolicy sendThreads) {
        this.sendThreads = sendThreads;
    }

    public boolean getPersistUser() {
        return persistUser;
    }

    public void setPersistUser(boolean persistUser) {
        this.persistUser = persistUser;
    }

    public File getPersistenceDirectory() {
        return persistenceDirectory;
    }

    public void setPersistenceDirectory(File persistenceDirectory) {
        this.persistenceDirectory = persistenceDirectory;
    }

    public Set<String> getRedactedKeys() {
        return metadataState.getMetadata().redactedKeys;
    }

    public void setRedactedKeys(Set<String> redactedKeys) {
        metadataState.getMetadata().redactedKeys = redactedKeys;
    }

    public boolean getSendLaunchCrashesSynchronously() {
        return sendLaunchCrashesSynchronously;
    }

    public void setSendLaunchCrashesSynchronously(Boolean sendLaunchCrashesSynchronously) {
        this.sendLaunchCrashesSynchronously = sendLaunchCrashesSynchronously;
    }

    /**
     * load configuration
     *
     * @param context
     * @return Configuration
     */
    public static Configuration load(Context context) {
        return load(context, null);
    }

    /**
     * load configuration
     *
     * @param context
     * @param apiKey
     * @return Configuration
     */
    public static Configuration load(Context context, String apiKey) {
        return new ManifestConfigLoader().load(context, apiKey);
    }

    @Override
    public void addOnError(OnErrorCallback onError) {
        callbackState.addOnError(onError);
    }

    @Override
    public void removeOnError(OnErrorCallback onError) {
        callbackState.removeOnError(onError);
    }

    @Override
    public void addOnBreadcrumb(OnBreadcrumbCallback onBreadcrumb) {
        callbackState.addOnBreadcrumb(onBreadcrumb);
    }

    @Override
    public void removeOnBreadcrumb(OnBreadcrumbCallback onBreadcrumb) {
        callbackState.removeOnBreadcrumb(onBreadcrumb);
    }

    @Override
    public void addOnSession(OnSessionCallback onSession) {
        callbackState.addOnSession(onSession);
    }

    @Override
    public void removeOnSession(OnSessionCallback onSession) {
        callbackState.removeOnSession(onSession);
    }

    @Override
    public void addMetadata(String section, Map<String, Object> value) {
        metadataState.addMetadata(section, value);
    }

    @Override
    public void addMetadata(String section, String key, Object value) {
        metadataState.addMetadata(section, key, value);
    }

    @Override
    public void clearMetadata(String section) {
        metadataState.clearMetadata(section);
    }

    @Override
    public void clearMetadata(String section, String key) {
        metadataState.clearMetadata(section, key);
    }

    @Override
    public Map<String, Object> getMetadata(String section) {
        return metadataState.getMetadata(section);
    }

    @Override
    public Object getMetadata(String section, String key) {
        return metadataState.getMetadata(section, key);
    }

    @Override
    public User getUser() {
        return user;
    }

    /**
     * add plugin
     *
     * @param plugin
     */
    public void addPlugin(Plugin plugin) {
        plugins.add(plugin);
    }
}
